package com.mxcyk.org.插件.截屏;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import java.awt.image.*;

import com.uujava.minibox.ui.button.ImageJButton;

import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileFilter;
/**
 * @功能：简单的截屏
 * @version 1.00
 * @category 插件
 * @author k
 * @time 2012-10-24
 *
 */
final public class CaptureScreen extends JWindow implements ActionListener {
	private static final long serialVersionUID = 1L;
	private ImageJButton jbExit, save;
	private ImageJButton clipboard;//区域截取到剪切板
	private ImageJButton jbStart;//重新截屏
	private JCheckBox recapture = new JCheckBox("重新截取屏幕区域");
	private JPanel c;
	private BufferedImage get;
	private  JWindow th = this;

	public CaptureScreen() {
		//super("梦续残缘工作室 by:k");
		initWindow();
		doStart();//启动截屏
	}

	private void initWindow() {
		JPanel buttonJP = buttonSet();
		//---------------------------------------------------------------------------
		//设置边框
		buttonJP.setBorder(BorderFactory.createTitledBorder(null, "",
				TitledBorder.LEADING, TitledBorder.TOP, new Font("Dialog",
						Font.BOLD, 12), new Color(51, 51, 51)));
		buttonJP.setLayout(new FlowLayout(FlowLayout.RIGHT));//右对齐
		//---------------------------------------------------------------------------
		add(c, BorderLayout.CENTER);
		add(buttonJP, BorderLayout.SOUTH);
		setSize(450, 300);
		setLocationRelativeTo(null);
		//setVisible(true);//刚运行默认不显示窗体
		setAlwaysOnTop(true);
	}

	/**
	 * @see 设置按钮
	 * @return JPanel
	 */
	public JPanel buttonSet() {
		char h=25,v=30;//按钮大小
		//======================================================
		jbExit = new ImageJButton("/images/tuiChu.png",h,v);
		jbStart=new ImageJButton("/images/cheXiao.png",h,v);//"重截"
		save = new ImageJButton("/images/baoCun.png",h,v);//"保存"
		clipboard = new ImageJButton("/images/wanCheng.png",h,v);//"区域截取到剪贴板"
		
		jbStart.setToolTipText("重新截取");
		jbExit.setToolTipText("退出");
		save.setToolTipText("保存");
		clipboard.setToolTipText("保存到剪切板");
		//======================================================
		jbStart.addActionListener(this);
		jbExit.addActionListener(this);
		save.addActionListener(this);
		save.setEnabled(false);
		clipboard.addActionListener(this);
		
		JPanel buttonJP = new JPanel();
		buttonJP.setOpaque(false);//背景透明
		c = new JPanel(new BorderLayout());

		buttonJP.add(jbStart);
		buttonJP.add(jbExit);
		buttonJP.add(save);
		buttonJP.add(clipboard);
		return buttonJP;
	}

	private void updates() {
		if (get != null) {
			ImageIcon ii = new ImageIcon(get);
			JLabel jl = new JLabel(ii);
			c.removeAll();
			//----------------------设置表框-----------------
			c.setBorder(BorderFactory.createTitledBorder(null, "",
					TitledBorder.LEADING, TitledBorder.TOP, new Font("Dialog",
							Font.BOLD, 12), new Color(51, 51, 51)));
			//----------------------------------------------
			c.add(jl, BorderLayout.CENTER);//
			SwingUtilities.updateComponentTreeUI(this);
		}
	}
	/**
	 * @see功能:调用此方法开始截屏
	 */
	private void doStart() {
		this.setVisible(false);
		try {
			Robot ro = new Robot();
			Dimension di = Toolkit.getDefaultToolkit().getScreenSize();
			 final JWindow jf = new JWindow();
			 ScreenImagePanel sip = new ScreenImagePanel(this, jf,
					ro.createScreenCapture(new Rectangle(0, 0, di.width,
							di.height)), di.width, di.height);
			jf.add(sip);
			jf.addKeyListener(new KeyListener() {

				@Override
				public void keyPressed(KeyEvent e) {
					// TODO Auto-generated method stub

				}

				@Override
				public void keyReleased(KeyEvent e) {
					if (e.getKeyCode() == 27) {//判断是否按Esc
						// over=false;
						jf.dispose();
						//th.setVisible(true);
					}
				}

				@Override
				public void keyTyped(KeyEvent e) {
					// TODO Auto-generated method stub

				}

			});
			jf.setSize(di);
			jf.setVisible(true);
			jf.setAlwaysOnTop(true);
		} catch (Exception exe) {
			exe.printStackTrace();
		}
	}

	private void doSave() {
		try {
			JFileChooser jfc = new JFileChooser(".");
			
			jfc.addChoosableFileFilter(new JPGfilter());
			jfc.addChoosableFileFilter(new BMPfilter());
			// 设置默认的文件管理器。如果不设置,则最后添加的文件过滤器为默认过滤器
			jfc.setFileFilter(new PNGfilter());
			if (jfc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
				File file = jfc.getSelectedFile();
				
				String about = "PNG";
				String ext = file.toString().toLowerCase();
				FileFilter ff = jfc.getFileFilter();
				
				if (ff instanceof JPGfilter) {
					if (!ext.endsWith(".jpg")) {
						String ns = ext + ".jpg";
						file = new File(ns);
						about = "JPG";
					}
				} else if (ff instanceof PNGfilter) {
					if (!ext.endsWith(".png")) {
						String ns = ext + ".png";
						file = new File(ns);
						about = "PNG";
					}
				} else if (ff instanceof BMPfilter) {
					if (!ext.endsWith(".bmp")) {
						String ns = ext + ".bmp";
						file = new File(ns);
						about = "BMP";
					}
				}

				if (ImageIO.write(get, about, file)) {//保存成功
					//JOptionPane.showMessageDialog(this, "保存成功！");
					exit();//保存后默认退出
				} else
					JOptionPane.showMessageDialog(this, "保存失败！");
			}
		} catch (Exception exe) {
			exe.printStackTrace();
		}
	}
	
	private void visible(){
		th.setVisible(false	);
	}
	//结束本窗体
	public void exit(){
		th.setVisible(false);//设置窗体不显示
		th.dispose();//撤销窗体
	}
	//判断触发的按钮
	public void actionPerformed(ActionEvent ae) {
		if (ae.getSource() == jbExit){
			exit();// 推出
		}else if (ae.getSource() == save){
			visible();
			doSave();
		}else if (ae.getSource() == jbStart) {// 在这边有个BUG当点击重新截屏时会出现在截屏的窗体还没来得及隐藏就已经开始截屏了
			th.setVisible(false);
			doStart();// 开始截屏
		} else if (ae.getSource() == clipboard) {// 截屏到剪切板
			visible();
			doClipboard();
		}
		exit();
	}

	//截屏到剪切板
	private void doClipboard() {
		if (recapture.isSelected()) {
			this.setVisible(false);
			new Screenshot(this);
		} else {
			try {
				/*new ClipboardUtil().writeToClipboard(get);
				JOptionPane.showMessageDialog(this, "指定区域截图已复制到剪贴板！");*/
			} catch (Exception ex) {
				JOptionPane.showMessageDialog(this, "指定区域截图未复制到剪贴板！");
			} finally {
				this.setVisible(true);
			}
		}
	}

	// 一个文件后缀名选择器
	private class JPGfilter extends FileFilter {
		public boolean accept(File file) {
			return file.toString().toLowerCase().endsWith(".jpg")
					|| file.toString().toLowerCase().endsWith(".jpeg")
					|| file.isDirectory();
		}

		public String getDescription() {
			return "*.JPG,*.JPEG(JPG,JPEG图像)";
		}
	}

	private class PNGfilter extends FileFilter {
		public boolean accept(File file) {
			return file.toString().toLowerCase().endsWith(".png")
					|| file.isDirectory();
		}

		public String getDescription() {
			return "*.PNG(PNG图像)";
		}
	}

	private class BMPfilter extends FileFilter {
		public boolean accept(File file) {
			return file.toString().toLowerCase().endsWith(".bmp")
					|| file.isDirectory();
		}

		public String getDescription() {
			return "*.BMP(BMP位图)";
		}
	}

	// 一个暂时类，用于显示当前的屏幕图像
	private class ScreenImagePanel extends JPanel implements MouseListener,
			MouseMotionListener {
		private static final long serialVersionUID = 1L;
		private BufferedImage bi;
		private int width, height;
		private int startX, startY, endX, endY, tempX, tempY;
		private JWindow jf;
		private Rectangle select = new Rectangle(0, 0, 0, 0);// 表示选中的区域
		private States current = States.DEFAULT;// 表示当前的编辑状态
		private Rectangle[] rec;// 表示八个编辑点的区域
		private CaptureScreen cs;
		private ImageIcon icon = new ImageIcon();

		public ScreenImagePanel(CaptureScreen cs, JWindow jf, BufferedImage bi,
				int width, int height) throws AWTException {
			this.jf = jf;
			this.bi = bi;
			this.width = width;
			this.height = height;
			this.cs = cs;
			this.addMouseListener(this);
			this.addMouseMotionListener(this);
			initRecs();
		}

		private void initRecs() {
			rec = new Rectangle[8];
			for (int i = 0; i < rec.length; i++)
				rec[i] = new Rectangle();
		}

		public void paintComponent(Graphics g) {
			g.drawImage(bi, 0, 0, width, height, this);
			g.setColor(Color.RED);
			g.drawLine(startX, startY, endX, startY);
			g.drawLine(startX, endY, endX, endY);
			g.drawLine(startX, startY, startX, endY);
			g.drawLine(endX, startY, endX, endY);
			int x = startX < endX ? startX : endX;
			int y = startY < endY ? startY : endY;
			select = new Rectangle(x, y, Math.abs(endX - startX), Math.abs(endY
					- startY));
			int x1 = (startX + endX) / 2;
			int y1 = (startY + endY) / 2;
			g.fillRect(x1 - 2, startY - 2, 5, 5);
			g.fillRect(x1 - 2, endY - 2, 5, 5);
			g.fillRect(startX - 2, y1 - 2, 5, 5);
			g.fillRect(endX - 2, y1 - 2, 5, 5);
			g.fillRect(startX - 2, startY - 2, 5, 5);
			g.fillRect(startX - 2, endY - 2, 5, 5);
			g.fillRect(endX - 2, startY - 2, 5, 5);
			g.fillRect(endX - 2, endY - 2, 5, 5);
			rec[0] = new Rectangle(x - 5, y - 5, 10, 10);
			rec[1] = new Rectangle(x1 - 5, y - 5, 10, 10);
			rec[2] = new Rectangle((startX > endX ? startX : endX) - 5, y - 5,
					10, 10);
			rec[3] = new Rectangle((startX > endX ? startX : endX) - 5, y1 - 5,
					10, 10);
			rec[4] = new Rectangle((startX > endX ? startX : endX) - 5,
					(startY > endY ? startY : endY) - 5, 10, 10);
			rec[5] = new Rectangle(x1 - 5, (startY > endY ? startY : endY) - 5,
					10, 10);
			rec[6] = new Rectangle(x - 5, (startY > endY ? startY : endY) - 5,
					10, 10);
			rec[7] = new Rectangle(x - 5, y1 - 5, 10, 10);
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);
			g2d.setColor(new Color(150, 150, 150));
			AlphaComposite composite = AlphaComposite.getInstance(
					AlphaComposite.SRC_OVER, 60 / 100.0F);
			g2d.setComposite(composite);
			g2d.fill(new RoundRectangle2D.Float(0, 0, this.getWidth(), this
					.getHeight(), 0, 0));
			if (endY != startY && endX != startX) {
				icon.setImage(bi.getSubimage(x, y, Math.abs(endX - startX),
						Math.abs(endY - startY)));
				g.drawImage(icon.getImage(), x, y, this);
			}
		}

		public void mouseMoved(MouseEvent me) {
			if (select.contains(me.getPoint())) {
				this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
				current = States.MOVE;
			} else {
				States[] st = States.values();
				for (int i = 0; i < rec.length; i++) {
					if (rec[i].contains(me.getPoint())) {
						current = st[i];
						this.setCursor(st[i].getCursor());
						return;
					}
				}
				current = States.DEFAULT;
			}
		}

		public void mouseExited(MouseEvent me) {

		}

		public void mouseEntered(MouseEvent me) {

		}

		public void mouseDragged(MouseEvent me) {
			int x = me.getX();
			int y = me.getY();
			if (current == States.MOVE) {
				startX += (x - tempX);
				startY += (y - tempY);
				endX += (x - tempX);
				endY += (y - tempY);
				tempX = x;
				tempY = y;
			} else if (current == States.EAST) {
				if (startX > endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
			} else if (current == States.NORTH) {
				if (startY < endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
			} else if (current == States.WEST) {
				if (startX < endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
			} else if (current == States.SOUTH) {
				if (startY > endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
			} else if (current == States.NORTH_EAST) {
				if (startX > endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
				if (startY < endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
			} else if (current == States.NORTH_WEST) {
				if (startX < endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
				if (startY < endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
			} else if (current == States.SOUTH_EAST) {
				if (startY > endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
				if (startX > endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
			} else if (current == States.SOUTH_WEST) {
				if (startY > endY) {
					startY += (y - tempY);
					tempY = y;
				} else {
					endY += (y - tempY);
					tempY = y;
				}
				if (startX < endX) {
					startX += (x - tempX);
					tempX = x;
				} else {
					endX += (x - tempX);
					tempX = x;
				}
			}

			else {
				startX = tempX;
				startY = tempY;
				endX = me.getX();
				endY = me.getY();
			}
			this.repaint();
		}

		public void mousePressed(MouseEvent me) {
			tempX = me.getX();
			tempY = me.getY();
			
			if ( me.getButton() == MouseEvent.BUTTON3) {
	            //点击右键
				jf.dispose();
				exit();//默认退出窗体
	        }
		}

		public void mouseReleased(MouseEvent me) {
			if (me.isPopupTrigger()) {
				if (current == States.MOVE) {
					startX = 0;
					startY = 0;
					endX = 0;
					endY = 0;
					repaint();
				} else {
					jf.dispose();
					updates();
				}
			}
		}

		public void mouseClicked(MouseEvent me) {
			if (me.getButton() == 1 && me.getClickCount() == 2) {
				Point p = me.getPoint();
				if (select.contains(p)) {
					if (select.x + select.width < this.getWidth()
							&& select.y + select.height < this.getHeight()) {
						get = bi.getSubimage(select.x, select.y, select.width,
								select.height);
					} else {
						int wid = select.width, het = select.height;
						if (select.x + select.width >= this.getWidth()) {
							wid = this.getWidth() - select.x;
						}
						if (select.y + select.height >= this.getHeight()) {
							het = this.getHeight() - select.y;
						}
						get = bi.getSubimage(select.x, select.y, wid, het);
					}
					updates();
					if (get.getWidth() + 20 > 300) {
						cs.setLocation(
								(bi.getWidth() - get.getWidth() - 20) / 2,
								(bi.getHeight() - get.getHeight() - 80) / 2);
						cs.setSize(get.getWidth(), get.getHeight());
					} else {
						cs.setLocation((bi.getWidth() - 450) / 2,
								(bi.getHeight() - get.getHeight() - 80) / 2);
						cs.setSize(300, get.getHeight());//如果宽度小于300
					}
					cs.setVisible(true);
					jf.dispose();
					save.setEnabled(true);
					recapture.setEnabled(true);
				}
			} else if (me.getButton() == 3) {
				jf.dispose();
				cs.setVisible(true);
			}
		}
	}

	public static void main(String args[]) {
		CaptureScreen star=new CaptureScreen();
		//star.doStart();
	}
}

enum States {
	NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)), NORTH(new Cursor(
			Cursor.N_RESIZE_CURSOR)), NORTH_EAST(new Cursor(
			Cursor.NE_RESIZE_CURSOR)), EAST(new Cursor(Cursor.E_RESIZE_CURSOR)), SOUTH_EAST(
			new Cursor(Cursor.SE_RESIZE_CURSOR)), SOUTH(new Cursor(
			Cursor.S_RESIZE_CURSOR)), SOUTH_WEST(new Cursor(
			Cursor.SW_RESIZE_CURSOR)), WEST(new Cursor(Cursor.W_RESIZE_CURSOR)), MOVE(
			new Cursor(Cursor.MOVE_CURSOR)), DEFAULT(new Cursor(
			Cursor.DEFAULT_CURSOR));
	private Cursor cs;

	States(Cursor cs) {
		this.cs = cs;
	}

	public Cursor getCursor() {
		return cs;
	}
}
